package com.iwdnb.gkgz.common.utils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.alibaba.fastjson.JSON;

import cn.hutool.core.date.DateUtil;
import com.iwdnb.bmnf.common.exception.ExceptionsEnhancer;
import com.iwdnb.bmnf.common.utils.ClassUtils;
import lombok.Data;

public class WorkDayUtils {
    private static final String WORK_DAY_CONFIG_PATH = "workDay.json";
    private static final WorkDayInfo WORK_DAY_INFO;

    static {
        String content = ClassUtils.getFileContentList(WORK_DAY_CONFIG_PATH).get(0);
        WORK_DAY_INFO = JSON.parseObject(content, WorkDayInfo.class);
    }

    public static Date offsetWorkDay(String date, int offset) {
        return offsetWorkDay(DateUtil.parse(date), offset);
    }

    public static Date offsetWorkDay(Date date, int offset) {
        if (offset == 0) {
            return date;
        }
        while (offset != 0) {
            if (offset > 0) {
                date = getNextWorkDay(date);
                offset--;
            } else {
                date = getBeforeWorkDay(date, -offset);
                offset++;
            }
        }
        return date;
    }

    public static Date getNextWorkDay() {
        return getNextWorkDay(new Date());
    }

    public static Date getNextWorkDay(Date date) {
        for (int i = 1; i < 30; i++) {
            Date nextDay = DateUtil.offsetDay(date, i);
            if (isWorkDay(nextDay)) {
                return nextDay;
            }
        }
        ExceptionsEnhancer.createError("未找到下一个工作日,请联系管理员");
        return null;
    }

    public static Date getBeforeWorkDay(Date date, int index) {
        int temp = 0;
        for (int i = 1; i < 300; i++) {
            date = DateUtil.offsetDay(date, -1);
            if (isWorkDay(date)) {
                temp++;
                if (temp == index) {
                    return date;
                }
            }
        }
        return null;
    }

    public static boolean isWorkDay(Date date) {
        return WORK_DAY_INFO.isWorkDay(date);
    }

    public static int betweenDay(Date begin, Date end) {
        begin = DateUtil.beginOfDay(begin);
        end = DateUtil.beginOfDay(end);
        Date date = begin;
        int between = 0;
        while (date.before(end)) {
            between++;
            date = getNextWorkDay(date);
        }

        return between;
    }

    public static Date getNextStockTradeDay(Date date) {
        for (int i = 1; i < 30; i++) {
            date = getNextWorkDay(date);
            if (isWeekNormalDay(date)) {
                return date;
            }
        }
        ExceptionsEnhancer.createError("未找到下一个交易日,请联系管理员");
        return null;
    }

    public static boolean isWeekNormalDay(Date date) {
        int index = DateUtil.dayOfWeek(date);
        if (index == 1 || index == 7) {
            return false;
        }
        return true;
    }

    public static List<Date> getWorkDayList(String begin, String end) {
        return getWorkDayList(DateUtil.parse(begin), DateUtil.parse(end));
    }

    public static List<Date> getWorkDayList(Date begin, Date end) {
        List<Date> dateList = new ArrayList<>();
        do {
            dateList.add(begin);
            begin = WorkDayUtils.getNextWorkDay(begin);
        } while (!begin.after(end));
        return dateList;
    }

    @Data
    public static class WorkDayInfo {
        private List<String> workday;

        private List<String> holiday;

        public boolean isWorkDay(Date date) {
            String dateStr = DateUtil.formatDate(date);
            if (holiday.contains(dateStr)) {
                return false;
            }
            if (workday.contains(dateStr) && isWeekNormalDay(date)) {
                return true;
            }
            return isWeekNormalDay(date);
        }

        public boolean isHoliday(Date date) {
            return !isWorkDay(date);
        }

    }

}
